package yuqueHandler

import (
	"errors"
	"log"
	"strings"

	"yuqueDownloader/entity"

	"golang.org/x/net/html"
)

type SuperHandler struct {
	Strong  bool              // 是否加粗
	Toc     *entity.TocStruct // toc 信息
	Content *string           // md 文档内容
	Node    *html.Node

	isOlTag bool
	olIdx   int
}

type HandlerInterface interface {
	preHandle()
	doHandle()
	postHandle()
}

// 处理前操作
func (thisReceiver *SuperHandler) preHandle() {
	// log.Println("SuperHandler preHandle....", thisReceiver.Node)
}

// 处理中
func (thisReceiver *SuperHandler) doHandle() {
	// log.Println("SuperHandler doHandle....", thisReceiver.Node)
}

// 处理后操作
func (thisReceiver *SuperHandler) postHandle() {
	// log.Println("SuperHandler postHandle....", thisReceiver.Node)
}

// 递归处理所有节点
func (thisReceiver *SuperHandler) DoAllNode(node *html.Node) {
	if node == nil {
		return
	}
	// 先处理当前节点
	// 获取 handler
	handler, err := thisReceiver.genHandler(node)
	if err != nil {
		log.Println("genHandler ERROR:", err)
		return
	}

	handler.preHandle()

	handler.doHandle()

	// 然后处理子节点
	thisReceiver.DoAllNode(node.FirstChild)

	handler.postHandle()

	// 再处理 Next 节点
	thisReceiver.DoAllNode(node.NextSibling)

}

// 开始处理节点
func (thisReceiver *SuperHandler) genHandler(node *html.Node) (HandlerInterface, error) {
	if node == nil {
		// log.Println("node is nil or is NOT a ElementNode...")
		return nil, errors.New("node is nil or is NOT a ElementNode")
	}

	var handler HandlerInterface
	var err error

	var tempHandler SuperHandler = *thisReceiver
	tempHandler.Node = node

	if node.Type == html.TextNode {
		handler = &TextHandler{
			SuperHandler: tempHandler,
		}
		return handler, nil
	}
	switch strings.ToLower(node.Data) {
	case "span":
		handler = &SpanHandler{
			SuperHandler: tempHandler,
		}
	case "h", "h1", "h2", "h3", "h4", "h5", "h6", "h7":
		handler = &HHandler{
			SuperHandler: tempHandler,
		}
	case "ol", "ul":
		handler = &OlUlHandler{
			SuperHandler: tempHandler,
		}
	case "li":
		handler = &LiHandler{
			SuperHandler: tempHandler,
		}
	case "p":
		handler = &PHandler{
			SuperHandler: tempHandler,
		}
	default:
		// log.Println("未匹配对应处理类", node.Data)
		handler = &IgnoreHandler{}
		err = errors.New("未匹配对应处理类 " + node.Data)
	}

	return handler, err
}
